-- [ja] SM5非対応パラメータを保存する 
--[[ UOPの構成
グループフォルダ名/曲フォルダ名|パラメータ名１:パラメータ値１|パラメータ名２:パラメータ値２|…;
--]]

local UOPPath="Save/UserPrefs/_UOP/UnOfficialParameter.txt"
local UOPData="";

local UOPV={};

function OpenUOP()
	if FILEMAN:DoesFileExist(UOPPath) then
		UOPData="";
		local f=RageFileUtil.CreateRageFile();
		f:Open(UOPPath,1);
		f:Seek(0);
		while not f:AtEOF() do
			local l=f:GetLine();
			local sp=split("%|#%|",l);
			UOPV[string.lower(sp[1])]=l;
		end;
		UOPData="Loaded";--f:Read();
		f:Close();
		f:destroy();
	else
		UOPData="Loaded";
		SaveUOP();
	end;
end;

function SaveUOP()
	-- [ja] 破損チェック用バックアップロード 
	local UOPData_bk="";
	if FILEMAN:DoesFileExist(UOPPath..".old") then
		local f_bk=RageFileUtil.CreateRageFile();
		f_bk:Open(UOPPath..".old",1);
		UOPData_bk=f_bk:Read();
		f_bk:Close();
		f_bk:destroy();
	end;
	if string.len(UOPData_bk)>string.len(UOPData) then
		-- [ja] ファイル破損のため、バックアップファイルに書き換える 
		UOPData=UOPData_bk;
	end;
	-- [ja] バックアップ保存 
	if FILEMAN:DoesFileExist(UOPPath) then
		UOPData_bk="";
		local f=RageFileUtil.CreateRageFile();
		f:Open(UOPPath,1);
		UOPData_bk=f:Read();
		f:Close();
		f:destroy();
		local f=RageFileUtil.CreateRageFile();
		f:Open(UOPPath..".old",2);
		f:Write(UOPData_bk);
		f:Close();
		f:destroy();
	end;
	UOPData_bk="";
	UOPData="";
	-- [ja] ファイル保存 
	local f=RageFileUtil.CreateRageFile();
	f:Open(UOPPath,2);
	for fn in pairs(UOPV) do
		if UOPV[fn] then
			if UOPV[fn]~="" then
				UOPData=UOPData..UOPV[fn].."\r\n";
			end;
		end;
	end;
	f:Write(UOPData);
	f:Close();
	f:destroy();
	UOPData="Loaded";
end;

function IsUOP()
	if UOPData=="" then
		return false;
	end;
	return true;
end;

function ReadUOP(song,prm)
--[[
	読み込み順
	SM/SSCファイル直書きデータ＞UOP＞SMEXP 
]]
	local ret="";
	-- [ja] 直書きされているかを確認 
	local chk="";
	if song then
		chk=UOP_GetSMParameter(song,prm);
		local lprm=string.lower(prm)
		local hituop=false;
		local foldername=string.lower(song:GetGroupName().."/"..UOP_GetSong2Folder(song).."/")
		--[[
		local finds,finde=string.find(UOPData,""..foldername,0,true);
		local _s,_e,_d,data;
		if finds then
			hituop=true;
			_s,_e,_d=string.find(UOPData,"%|#%|(.-);",finds,false);
			data=split("|",_d);
			for i=1,#data do
				_d=split(":",data[i])
				if string.lower(_d[1])==lprm then
					ret=_d[2];
					break;
				end;
			end;
		else
			hituop=false;
		end;
		--]]
		local data;
		if UOPV[foldername] then
			hituop=true;
			--_s,_e,_d=string.find(UOPData,"%|#%|(.-);",finds,false);
			local prm_tmp="";
			prm_tmp=split("%|#%|",UOPV[foldername]);
			data=split("|",prm_tmp[2]);
			for i=1,#data do
				_d=split(":",data[i])
				if string.lower(_d[1])==lprm then
					ret=split(";",_d[2])[1];
					break;
				end;
			end;
		else
			hituop=false;
		end;
		-- [ja] 見つからないのでSMEXPを探す 
		if ret=="" and chk=="" then
			chk=UOP_GetExtendedParameter(song,prm);
		end;
		-- [ja] 直書きデータが更新されている or 初読み取り 
		if (ret~=chk and chk~="") or (ret=="" and chk=="" and not hituop) then
			--_SYS("!")
			ret=chk;
			local prm_tmp="";
			if UOPV[foldername] then
				local prm_flag=false;
				for i=1,#data do
					_d=split(":",data[i])
					if string.lower(_d[1])==lprm then
						prm_flag=true;
						prm_tmp=prm_tmp.."|".._d[1]..":"..ret;
					else
						prm_tmp=prm_tmp.."|".._d[1]..":".._d[2];
					end;
				end;
				if not prm_flag then
					prm_tmp=prm_tmp.."|"..prm..":"..ret;
				end;
			else
				prm_tmp="|"..prm..":"..ret;
			end;
			-- [ja] UOPに書き込み（保存はしない） 
			--      こうすることで、一回でも読み込めばあとは高速読み込み可能 
			-- TODO
			UOPV[foldername]=foldername.."|#"..prm_tmp..";";
			--UOPData=UOPData_tmp..foldername.."|#"..prm_tmp..";\r\n";
		end;
	end;
	return ret;
end;

--[ja] 以下、 99 waiei.luaにもあるけどこれ単独でも動くように 
function UOP_GetSong2Folder(song)
	if song then
		local _t=split("/",song:GetSongDir())
		return _t[#_t-1];
	end;
	return "";
end;

--[ja] SMファイルで指定したパラメータの内容を読み取る  
function UOP_GetSMParameter(song,prm)
	local st=song:GetAllSteps();
	if #st<1 then
		return "";
	end;
	local t;
	t=st[1]:GetFilename();
	if not FILEMAN:DoesFileExist(t) then
		return "";
	end;
	--[ja] 形式ではじく 
	local lt=string.lower(t);
	if not string.find(lt,".*%.sm") and not string.find(lt,".*%.ssc") then
		return "";
	end;
	local f=RageFileUtil.CreateRageFile();
	f:Open(t,1);
	-- [ja] 複数行を考慮していったん別変数に代入する 
	local gl="";
	local pl=string.lower(prm);
	local l;
	while true do
		l=f:GetLine();
		local ll=string.lower(l);
		if string.find(ll,"#notes:.*") or f:AtEOF() then
			break;
		-- [ja] BOM考慮して .* を頭につける 
		elseif (string.find(ll,"^.*#"..pl..":.*") and (not string.find(ll,"^%/%/.*"))) or gl~="" then
			gl=gl..""..split("//",l)[1];
			if string.find(ll,".*;") then
				break;
			end;
		end;
	end;
	local tmp={};
	if gl=="" then
		tmp={""};
	else
		tmp=split(":",gl);
		if tmp[2]==";" then
			tmp[1]="";
		else
			if #tmp>2 then
				tmp[1]=tmp[2];
				for i=3,#tmp do
					tmp[1]=tmp[1]..":"..split(";",tmp[i])[1];
				end;
			else
				tmp[1]=split(";",tmp[2])[1];
			end;
		end;
	end;
	f:Close();
	f:destroy();
	return tmp[1];
end;

-- [ja] 外部ファイルとして保存されたSM5非対応コマンドを読み込む 
--      ※waiei 1.32以降出力廃止 
function UOP_GetExtendedParameter(song,prm)
	local f={};
	local ret={};
	local lprm=string.lower(prm)
	f=FILEMAN:GetDirListing(song:GetSongDir());
	for i=1,#f do
		if string.find(string.lower(f[i]),lprm..";.*%.smexp") then
			ret=split(";",f[i]);
			ret=split(".smexp",ret[2]);
			return ret[1];
		end;
	end;
	return "";
end;